package com.example.mychess;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
 * SocketUtil类提供了一系列与Socket编程相关的便捷方法，包括创建Socket连接、发送消息和接收消息，并包含关闭输入输出流的方法。
 *
 * @author [Your Name]
 * @package com.example.mychess
 */

public class SocketUtil {
    /**
     * 根据指定的IP地址和端口号创建一个新的Socket连接。
     *
     * @param ip 目标服务器的IP地址
     * @param port 服务器监听的端口号
     * @return 创建成功则返回一个Socket实例，若发生IOException，则打印堆栈信息并返回null
     */
    public static Socket create(String ip,int port){
        try {
            return new Socket(InetAddress.getByName(ip),port);
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据给定的端口号创建一个新的Socket连接，连接到本地主机。
     *
     * @param port 本地服务器监听的端口号
     * @return 创建成功则返回一个Socket实例，若发生IOException，则打印堆栈信息并返回null
     */
    public static Socket createLocalHost(int port){
        try {
            return new Socket(InetAddress.getLocalHost(),port);
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 向指定的Socket连接发送一个Message对象（假设Message是实现了序列化的类）。
     *
     * @param s 已建立连接的Socket对象
     * @param msg 要发送的对象，通常是一个实现了Serializable接口的消息对象
     * @throws RuntimeException 如果在发送过程中发生IOException，则包装成RuntimeException抛出
     */
    public static void send(Socket s,Message msg){
        OutputStream os=null;
        ObjectOutputStream oos=null;
        try {
            os=s.getOutputStream();
            oos=new ObjectOutputStream(os);
            oos.writeObject(msg);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    /**
     * 从指定的Socket连接接收一个Object对象，此方法假设接收到的对象是由ObjectOutputStream写入的。
     *
     * @param s 已建立连接的Socket对象
     * @return 返回从Socket中读取的对象，若发生任何Exception，则包装成RuntimeException抛出
     */
    public static Object receive(Socket s){
        InputStream is=null;
        ObjectInputStream ois=null;
        try {
            is=s.getInputStream();
            ois=new ObjectInputStream(is);
            return ois.readObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 安全地关闭给定的输入流和输出流。如果流非空且未关闭，尝试关闭它们，同时捕获并打印可能发生的IOException。
     *
     * @param is 需要关闭的InputStream实例
     * @param os 需要关闭的OutputStream实例
     */
    public void close(InputStream is,OutputStream os){
        if(is!=null){
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(os!=null){
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
